#ifndef prs_FrmControl_H
#define prs_FrmControl_H

#include "frm_control_TPanel.h"
#include "prs_FrmStyle.h"
#include "prs_FrmGeom.h"
#include "prs_FrmUseTemplate.h"

namespace prs {

///////////////////////////////////////////////////////////////////////////////
struct TNodeFrmControl;
///////////////////////////////////////////////////////////////////////////////

enum EControlType {
  EControlType_Unknown,
  EControlType_RowCaption,
  EControlType_Col,
};
  
///////////////////////////////////////////////////////////////////////////////

struct TMessage_Control : public TMessage_Base
{
  TNodeFrmControl *Sender;
  //
  TMessage_Control();
  //
  bool InControlType(EControlType V);
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_BeforeKeyboardKey : public TMessage_Control
{
  grf::TKeyboardKey &KeyboardKey;
  //
  TMessage_BeforeKeyboardKey(      
    grf::TKeyboardKey &KeyboardKey_
  )
  :KeyboardKey(KeyboardKey_){
  }  
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_AfterKeyboardKey : public TMessage_Control
{
  grf::TKeyboardKey &KeyboardKey;
  //
  TMessage_AfterKeyboardKey(      
    grf::TKeyboardKey &KeyboardKey_
  )
  :KeyboardKey(KeyboardKey_){
  }  
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_BeforeKeyboardChar : public TMessage_Control
{
  grf::TKeyboardChar &KeyboardChar;
  //
  TMessage_BeforeKeyboardChar(      
    grf::TKeyboardChar &KeyboardChar_
  )
  :KeyboardChar(KeyboardChar_){
  }  
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_AfterKeyboardChar : public TMessage_Control
{
  grf::TKeyboardChar &KeyboardChar;
  //
  TMessage_AfterKeyboardChar(      
    grf::TKeyboardChar &KeyboardChar_
  )
  :KeyboardChar(KeyboardChar_){
  }  
};

///////////////////////////////////////////////////////////////////////////////

struct TMessage_SelectEnter : public TMessage_Control
{
  TMessage_SelectEnter() {
  }  
};

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmControl : public TNodeFrm
{
  TAttrId Id;
  TAttrString<attrName_ControlId> ControlId;
  TPropPointer<attrName_Style,TNodeStyle*> Style;
  TPropPointer<attrName_LocalStyle,TNodeStyle*> LocalStyle;
  TAttrNodeObject<attrName_Geometry,TNodeFrmGeom> Geometry;
  //
  TNodeFrmControl() 
    :Id(this)
    ,ControlId(this)
    ,Style(this)
    ,LocalStyle(this)
    ,Geometry(this) 
  {}
 ~TNodeFrmControl() {}
  //
  virtual EControlType GetEControlType() { return EControlType_Unknown;}
  //
  bool CheckControlId(const svl::TString &Id_) { 
    return ControlId.GetValue().CompareIC(Id_);
  }
  //
  TNodeStyle *SearchStyleById(svl::TString StyleId){
    return TNodeStyle::searchStyleByIdFromChild(this,StyleId);
  }
  //
  template<class TNodeFrm___> static void setControlStyle(
    TNodeFrm___ *Node,
    const char  *StyleForControl
  ){
    TNodeFrm___::TControl *Control = Node->Control;
    if (!Control) {
      return;
    }
    TNodeStyle *NodeStyle = Node->LocalStyle; 
    if (!NodeStyle) {
      NodeStyle = Node->Style;
    }
    if (NodeStyle) {
      TNodeFrm___::TStyle *ControlStyle = dynamic_cast<TNodeFrm___::TStyle*>(
        NodeStyle->SearchStyleControlByType(StyleForControl)
      );
      if (ControlStyle) {
        Control->SetStyle(ControlStyle->Style.Value);
      }
    }
  }
  //
  template<class TNodeFrm___> static void setControlStyle(
    TNodeFrm___ *Node
  ){
    setControlStyle(Node,Node->NodeType.value());
  }
  
protected:
  virtual void           TNode_SetPropPointerValue(TAttrPointerBase &Attr,svl::TPointer *V);
  virtual svl::TPointer *TNode_GetPropPointerValue(TAttrPointerBase &Attr);
  //
  TNodeStyle *vStyle,*vLocalStyle;
  
private:
  svl_Except;
};

///////////////////////////////////////////////////////////////////////////////

struct TNodeFrmControlEvents : public frm::control::TPanelEvents
{
  TNodeFrmControlEvents(
    TNodeFrmControl *Control
  )
  :control(*Control){
  }
  //
  virtual void Event(TBeforeKeyboardKey &Param);
  virtual void Event(TAfterKeyboardKey  &Param);
  //
  virtual void Event(TBeforeKeyboardChar &Param);
  virtual void Event(TAfterKeyboardChar  &Param);
  //
  virtual void Event(TSelectEnter &Param);

private:
  TNodeFrmControl &control;
};

///////////////////////////////////////////////////////////////////////////////
}

#endif
